package sma.agents;
import java.util.Hashtable;

import jade.core.Agent;
import jade.core.behaviours.*;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.MessageTemplate;

public class bookSellerAgent extends Agent{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@SuppressWarnings("rawtypes")
	private Hashtable catalogue;
	private bookSellerGui myGUI;
	
	@SuppressWarnings({"rawtypes" })
	protected void setup(){
		catalogue = new Hashtable();
		myGUI = new bookSellerGui(this);
		myGUI.showGui();
		
//		for(int i=0; i < this.catalogue.size(); i++)
		System.out.println("Catalogue : " + this.catalogue.toString());
		
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(this.getAID());
		ServiceDescription sd = new ServiceDescription();
		sd.setType("book-selling");
		sd.setName("JADE-book-trading");
		
		dfd.addServices(sd);
		
		try {
			DFService.register(this, dfd);
		} catch (FIPAException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		this.addBehaviour(new OfferRequestsServer());
		this.addBehaviour(new PurchaseOrdersServer());
	}
	
	protected void takeDown(){
		
		try {
			DFService.deregister(this);
		} catch (FIPAException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		myGUI.dispose();
		System.out.println("Seller agent " + (String)this.getAID().getName() + " terminated !!!");
	}
	
	public void updateCatalogue(final String title, final int price){
		this.addBehaviour(new OneShotBehaviour(){
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@SuppressWarnings("unchecked")
			public void action(){
				catalogue.put(title, new Integer(price));
				System.out.println("Insert catalogue : " + title + " " + price);
			}
		});
	}
	
	private class OfferRequestsServer extends CyclicBehaviour{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public void action(){
			System.out.println("OfferRequestsServer");
			System.out.println("Catalogue : " + catalogue.toString());
			jade.lang.acl.MessageTemplate mt = MessageTemplate.MatchPerformative(jade.lang.acl.ACLMessage.CFP);
			jade.lang.acl.ACLMessage msg = this.myAgent.receive(mt);
			if (msg != null){
				String title = msg.getContent();
				jade.lang.acl.ACLMessage msgReply = msg.createReply();
				Integer price = (Integer) catalogue.get(title);
				if (price != null){
					msgReply.setPerformative(jade.lang.acl.ACLMessage.PROPOSE);
					msgReply.setContent(String.valueOf(price.intValue()));
				}
				else{
					msgReply.setPerformative(jade.lang.acl.ACLMessage.REFUSE);
					msgReply.setContent("not-available");
				}
				this.myAgent.send(msgReply);
			}
			else{
				this.block();
			}
		}
		
	}
	
	private class PurchaseOrdersServer extends CyclicBehaviour{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public void action(){
			System.out.println("PurchaseOrdersServer");
			System.out.println("Catalogue : " + catalogue.toString());
			jade.lang.acl.MessageTemplate mt = MessageTemplate.MatchPerformative(jade.lang.acl.ACLMessage.CFP);
			jade.lang.acl.ACLMessage msg = this.myAgent.receive(mt);
			if(msg != null){
				String title = msg.getContent();
				jade.lang.acl.ACLMessage msgReply = msg.createReply();
				Integer price = (Integer) catalogue.remove(title);
				System.out.println(price);
				if (price != null){
					msgReply.setPerformative(jade.lang.acl.ACLMessage.INFORM);
					msgReply.setContent(title + " sold to agent " + msg.getSender().getName());
				}
				else{
					msgReply.setPerformative(jade.lang.acl.ACLMessage.FAILURE);
					msgReply.setContent("not-available");
				}
				this.myAgent.send(msgReply);
			}
			else{
				this.block();
			}
		}
	}
}
